home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / amitcp / netinet / raw_ip.c < prev    next >
C/C++ Source or Header  |  1993-08-12  |  9KB  |  317 lines

  1. RCS_ID_C="$Id: raw_ip.c,v 1.8 1993/06/04 11:16:15 jraja Exp $";
  2. /*
  3.  * Copyright (c) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>,
  4.  *                    Helsinki University of Technology, Finland.
  5.  *                    All rights reserved.
  6.  *
  7.  * HISTORY
  8.  * $Log: raw_ip.c,v $
  9.  * Revision 1.8  1993/06/04  11:16:15  jraja
  10.  * Fixes for first public release.
  11.  *
  12.  * Revision 1.7  1993/05/17  00:16:44  ppessi
  13.  * Changed RCS version. Added rcsid.
  14.  *
  15.  * Revision 1.6  1993/04/13  22:11:31  jraja
  16.  * Removed The extra argument of the rip_usrreq(), since it has one too many!
  17.  * The extra argument was passed to the raw_usrreq() which was wrong!
  18.  *
  19.  * Revision 1.5  93/04/11  22:26:48  22:26:48  jraja (Jarno Tapio Rajahalme)
  20.  * Added STKARGFUN to protocol input & output functions (if used in protosw).
  21.  * 
  22.  * Revision 1.4  93/04/05  19:06:18  19:06:18  jraja (Jarno Tapio Rajahalme)
  23.  * Changed storage of the spl functions  return values to type spl_t.
  24.  * Added include for conf.h to every .c file.
  25.  * 
  26.  * Revision 1.3  93/03/22  16:59:32  16:59:32  jraja (Jarno Tapio Rajahalme)
  27.  * Changed bcopy()s and bzero()s with word aligned pointers to
  28.  * aligned_b(copy|zero) ar aligned_b(copy|zero)_const. The latter is for calls
  29.  * in which the size is constant.
  30.  * These can be disabled by defining NOALIGN.
  31.  *  Converted bcopys doing structure copies (on aligned pointers) to structure
  32.  * assignments, since at least SASC produces better code with assignment.
  33.  * 
  34.  * Revision 1.2  93/02/26  09:26:49  09:26:49  jraja (Jarno Tapio Rajahalme)
  35.  * Made this compile with ANSI C (added prototypes).
  36.  * Removed extra argument from call to raw_usrreq()
  37.  * (yes, prototypes do wonders :-)
  38.  * 
  39.  * Revision 1.1  92/11/17  16:30:00  16:30:00  jraja (Jarno Tapio Rajahalme)
  40.  * Initial revision
  41.  * 
  42.  */
  43.  
  44. /*
  45.  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
  46.  * All rights reserved.
  47.  *
  48.  * Redistribution and use in source and binary forms, with or without
  49.  * modification, are permitted provided that the following conditions
  50.  * are met:
  51.  * 1. Redistributions of source code must retain the above copyright
  52.  *    notice, this list of conditions and the following disclaimer.
  53.  * 2. Redistributions in binary form must reproduce the above copyright
  54.  *    notice, this list of conditions and the following disclaimer in the
  55.  *    documentation and/or other materials provided with the distribution.
  56.  * 3. All advertising materials mentioning features or use of this software
  57.  *    must display the following acknowledgement:
  58.  *    This product includes software developed by the University of
  59.  *    California, Berkeley and its contributors.
  60.  * 4. Neither the name of the University nor the names of its contributors
  61.  *    may be used to endorse or promote products derived from this software
  62.  *    without specific prior written permission.
  63.  *
  64.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  65.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  66.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  67.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  68.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  69.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  70.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  71.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  72.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  73.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  74.  * SUCH DAMAGE.
  75.  *
  76.  *    @(#)raw_ip.c    7.8 (Berkeley) 7/25/90
  77.  */
  78.  
  79. #include <conf.h>
  80.  
  81. #include <sys/param.h>
  82. #include <sys/systm.h>
  83. #include <sys/malloc.h>
  84. #include <sys/mbuf.h>
  85. #include <sys/socket.h>
  86. #include <sys/protosw.h>
  87. #include <sys/socketvar.h>
  88. #include <sys/errno.h>
  89. #include <sys/synch.h>
  90.  
  91. #include <net/if.h>
  92. #include <net/route.h>
  93. #include <net/raw_cb.h>
  94.  
  95. #include <netinet/in.h>
  96. #include <netinet/in_systm.h>
  97. #include <netinet/ip.h>
  98. #include <netinet/ip_var.h>
  99. #include <netinet/in_pcb.h>
  100.  
  101. #include <netinet/raw_ip_protos.h>
  102. #include <netinet/ip_output_protos.h>
  103. #include <net/raw_usrreq_protos.h>
  104. #include <kern/uipc_socket2_protos.h>
  105.  
  106. /*
  107.  * Raw interface to IP protocol.
  108.  */
  109.  
  110. struct    sockaddr_in ripdst = { sizeof(ripdst), AF_INET };
  111. struct    sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
  112. struct    sockproto ripproto = { PF_INET };
  113. /*
  114.  * Setup generic address and protocol structures
  115.  * for raw_input routine, then pass them along with
  116.  * mbuf chain.
  117.  */
  118. void STKARGFUN
  119. rip_input(m)
  120.     struct mbuf *m;
  121. {
  122.     register struct ip *ip = mtod(m, struct ip *);
  123.  
  124.     ripproto.sp_protocol = ip->ip_p;
  125.     ripdst.sin_addr = ip->ip_dst;
  126.     ripsrc.sin_addr = ip->ip_src;
  127.     if (raw_input(m, &ripproto, (struct sockaddr *)&ripsrc,
  128.       (struct sockaddr *)&ripdst) == 0) {
  129.         ipstat.ips_noproto++;
  130.         ipstat.ips_delivered--;
  131.     }
  132. }
  133.  
  134. /*
  135.  * Generate IP header and pass packet to ip_output.
  136.  * Tack on options user may have setup with control call.
  137.  */
  138. #define    satosin(sa)    ((struct sockaddr_in *)(sa))
  139. int STKARGFUN
  140. rip_output(m, so)
  141.     register struct mbuf *m;
  142.     struct socket *so;
  143. {
  144.     register struct ip *ip;
  145.     register struct raw_inpcb *rp = sotorawinpcb(so);
  146.     register struct sockaddr_in *sin;
  147.  
  148.     /*
  149.      * If the user handed us a complete IP packet, use it.
  150.      * Otherwise, allocate an mbuf for a header and fill it in.
  151.      */
  152.     if (rp->rinp_flags & RINPF_HDRINCL)
  153.         ip = mtod(m, struct ip *);
  154.     else {
  155.         M_PREPEND(m, sizeof(struct ip), M_WAIT);
  156.         ip = mtod(m, struct ip *);
  157.         ip->ip_tos = 0;
  158.         ip->ip_off = 0;
  159.         ip->ip_p = rp->rinp_rcb.rcb_proto.sp_protocol;
  160.         ip->ip_len = m->m_pkthdr.len;
  161.         if (sin = satosin(rp->rinp_rcb.rcb_laddr)) {
  162.             ip->ip_src = sin->sin_addr;
  163.         } else
  164.             ip->ip_src.s_addr = 0;
  165.         if (sin = satosin(rp->rinp_rcb.rcb_faddr))
  166.             ip->ip_dst = sin->sin_addr;
  167.         ip->ip_ttl = MAXTTL;
  168.     }
  169.     return (ip_output(m,
  170.        (rp->rinp_flags & RINPF_HDRINCL)? (struct mbuf *)0: rp->rinp_options,
  171.         &rp->rinp_route, 
  172.        (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
  173. }
  174.  
  175. /*
  176.  * Raw IP socket option processing.
  177.  */
  178. int
  179. rip_ctloutput(op, so, level, optname, m)
  180.     int op;
  181.     struct socket *so;
  182.     int level, optname;
  183.     struct mbuf **m;
  184. {
  185.     int error = 0;
  186.     register struct raw_inpcb *rp = sotorawinpcb(so);
  187.  
  188.     if (level != IPPROTO_IP)
  189.         error = EINVAL;
  190.     else switch (op) {
  191.  
  192.     case PRCO_SETOPT:
  193.         switch (optname) {
  194.  
  195.         case IP_OPTIONS:
  196.             return (ip_pcbopts(&rp->rinp_options, *m));
  197.  
  198.         case IP_HDRINCL:
  199.             if (m == 0 || *m == 0 || (*m)->m_len < sizeof (int)) {
  200.                 error = EINVAL;
  201.                 break;
  202.             }
  203.             if (*mtod(*m, int *))
  204.                 rp->rinp_flags |= RINPF_HDRINCL;
  205.             else
  206.                 rp->rinp_flags &= ~RINPF_HDRINCL;
  207.             break;
  208.  
  209.         default:
  210.             error = EINVAL;
  211.             break;
  212.         }
  213.         break;
  214.  
  215.     case PRCO_GETOPT:
  216.         *m = m_get(M_WAIT, MT_SOOPTS);
  217.         switch (optname) {
  218.  
  219.         case IP_OPTIONS:
  220.             if (rp->rinp_options) {
  221.                 (*m)->m_len = rp->rinp_options->m_len;
  222.                 aligned_bcopy(mtod(rp->rinp_options, caddr_t),
  223.                     mtod(*m, caddr_t), (unsigned)(*m)->m_len);
  224.             } else
  225.                 (*m)->m_len = 0;
  226.             break;
  227.  
  228.         case IP_HDRINCL:
  229.             (*m)->m_len = sizeof (int);
  230.             *mtod(*m, int *) = rp->rinp_flags & RINPF_HDRINCL;
  231.             break;
  232.  
  233.         default:
  234.             error = EINVAL;
  235.             m_freem(*m);
  236.             *m = 0;
  237.             break;
  238.         }
  239.         break;
  240.     }
  241.     if (op == PRCO_SETOPT && *m)
  242.         (void)m_free(*m);
  243.     return (error);
  244. }
  245.  
  246. int
  247. rip_usrreq(so, req, m, nam, /*rights,*/ control)
  248.     register struct socket *so;
  249.     int req;
  250.     struct mbuf *m, *nam, /**rights,*/ *control;
  251. {
  252.     register int error = 0;
  253.     register struct raw_inpcb *rp = sotorawinpcb(so);
  254.  
  255.     switch (req) {
  256.  
  257.     case PRU_ATTACH:
  258.         if (rp)
  259.             panic("rip_attach");
  260.         MALLOC(rp, struct raw_inpcb *, sizeof *rp, M_PCB, M_WAITOK);
  261.         if (rp == 0)
  262.             return (ENOBUFS);
  263.         aligned_bzero_const((caddr_t)rp, sizeof(*rp));
  264.         so->so_pcb = (caddr_t)rp;
  265.         break;
  266.  
  267.     case PRU_DETACH:
  268.         if (rp == 0)
  269.             panic("rip_detach");
  270.         if (rp->rinp_options)
  271.             m_freem(rp->rinp_options);
  272.         if (rp->rinp_route.ro_rt)
  273.             RTFREE(rp->rinp_route.ro_rt);
  274.         if (rp->rinp_rcb.rcb_laddr)
  275.             rp->rinp_rcb.rcb_laddr = 0;
  276.         break;
  277.  
  278.     case PRU_BIND:
  279.         {
  280.         struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
  281.  
  282.         if (nam->m_len != sizeof(*addr))
  283.             return (EINVAL);
  284.         if ((ifnet == 0) ||
  285.             ((addr->sin_family != AF_INET) &&
  286.              (addr->sin_family != AF_IMPLINK)) ||
  287.             (addr->sin_addr.s_addr &&
  288.              ifa_ifwithaddr((struct sockaddr *)addr) == 0))
  289.             return (EADDRNOTAVAIL);
  290.         rp->rinp_rcb.rcb_laddr = (struct sockaddr *)&rp->rinp_laddr;
  291.         rp->rinp_laddr = *addr;
  292.         return (0);
  293.         }
  294.     case PRU_CONNECT:
  295.         {
  296.         struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);
  297.  
  298.         if (nam->m_len != sizeof(*addr))
  299.             return (EINVAL);
  300.         if (ifnet == 0)
  301.             return (EADDRNOTAVAIL);
  302.         if ((addr->sin_family != AF_INET) &&
  303.              (addr->sin_family != AF_IMPLINK))
  304.             return (EAFNOSUPPORT);
  305.         rp->rinp_rcb.rcb_faddr = (struct sockaddr *)&rp->rinp_faddr;
  306.         rp->rinp_faddr = *addr;
  307.         soisconnected(so);
  308.         return (0);
  309.         }
  310.     }
  311.     error = raw_usrreq(so, req, m, nam, /*rights,*/ control);
  312.  
  313.     if (error && (req == PRU_ATTACH) && so->so_pcb)
  314.         bsd_free(so->so_pcb, M_PCB);
  315.     return (error);
  316. }
  317.